package hawk.example.bookstore.update;

import static glz.hawkframework.support.ArgumentSupport.*;

import glz.hawkframework.dao.base.function.ColumnDescriptor;
import glz.hawkframework.dao.base.function.ColumnFunction;
import glz.hawkframework.dao.base.function.IRecord;
import glz.hawkframework.dao.base.function.RecordCreateDateTimeFunction;
import glz.hawkframework.dao.base.function.RecordCreateUserIdFunction;
import glz.hawkframework.dao.base.function.RecordIdFunction;
import glz.hawkframework.dao.base.function.RecordUpdateDateTimeFunction;
import glz.hawkframework.dao.base.function.RecordUpdateUserIdFunction;
import glz.hawkframework.dao.base.function.RecordVersionFunction;
import glz.hawkframework.sql.support.SqlColumn;
import glz.hawkframework.sql.support.impl.DefaultValueColumn;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Map to table: AUTHOR
 */
public class AuthorColumnUpdate implements IRecord {
    /**
     * Map to column: AUTHOR_ID
     */
    private SqlColumn authorId;
    /**
     * Map to column: AUTHOR_ID
     */
    private boolean authorIdUpdated = false;
    /**
     * 作者姓名
     * <p>Map to column: AUTHOR_NAME</p>
     */
    private SqlColumn authorName;
    /**
     * 作者姓名
     * <p>Map to column: AUTHOR_NAME</p>
     */
    private boolean authorNameUpdated = false;
    /**
     * Map to column: NATIONALITY
     */
    private SqlColumn nationality;
    /**
     * Map to column: NATIONALITY
     */
    private boolean nationalityUpdated = false;
    /**
     * Map to column: CONTACT
     */
    private SqlColumn contact;
    /**
     * Map to column: CONTACT
     */
    private boolean contactUpdated = false;
    /**
     * Map to column: CREATE_DATE_TIME
     */
    private SqlColumn createDateTime;
    /**
     * Map to column: CREATE_DATE_TIME
     */
    private boolean createDateTimeUpdated = false;
    /**
     * Map to column: UPDATE_DATE_TIME
     */
    private SqlColumn updateDateTime;
    /**
     * Map to column: UPDATE_DATE_TIME
     */
    private boolean updateDateTimeUpdated = false;
    /**
     * Map to column: DELETE_DATE_TIME
     */
    private SqlColumn deleteDateTime;
    /**
     * Map to column: DELETE_DATE_TIME
     */
    private boolean deleteDateTimeUpdated = false;
    /**
     * Map to column: CREATE_USER_ID
     */
    private SqlColumn createUserId;
    /**
     * Map to column: CREATE_USER_ID
     */
    private boolean createUserIdUpdated = false;
    /**
     * Map to column: UPDATE_USER_ID
     */
    private SqlColumn updateUserId;
    /**
     * Map to column: UPDATE_USER_ID
     */
    private boolean updateUserIdUpdated = false;
    /**
     * Map to column: DELETE_USER_ID
     */
    private SqlColumn deleteUserId;
    /**
     * Map to column: DELETE_USER_ID
     */
    private boolean deleteUserIdUpdated = false;
    /**
     * Map to column: RECORD_VERSION
     */
    private SqlColumn recordVersion;
    /**
     * Map to column: RECORD_VERSION
     */
    private boolean recordVersionUpdated = false;
    /**
     * This map holds the relations between function class and column
     */
    private final Map<Class<? extends ColumnFunction>, ColumnDescriptor<?>> functionMap = new HashMap<>();

    {
        functionMap.put(RecordIdFunction.class, new ColumnDescriptor<>("AUTHOR_ID", "authorId", this::getAuthorId, this::isAuthorIdUpdated, this::setAuthorId));
        functionMap.put(RecordCreateDateTimeFunction.class, new ColumnDescriptor<>("CREATE_DATE_TIME", "createDateTime", this::getCreateDateTime, this::isCreateDateTimeUpdated, this::setCreateDateTime));
        functionMap.put(RecordUpdateDateTimeFunction.class, new ColumnDescriptor<>("UPDATE_DATE_TIME", "updateDateTime", this::getUpdateDateTime, this::isUpdateDateTimeUpdated, this::setUpdateDateTime));
        functionMap.put(RecordCreateUserIdFunction.class, new ColumnDescriptor<>("CREATE_USER_ID", "createUserId", this::getCreateUserId, this::isCreateUserIdUpdated, this::setCreateUserId));
        functionMap.put(RecordUpdateUserIdFunction.class, new ColumnDescriptor<>("UPDATE_USER_ID", "updateUserId", this::getUpdateUserId, this::isUpdateUserIdUpdated, this::setUpdateUserId));
        functionMap.put(RecordVersionFunction.class, new ColumnDescriptor<>("RECORD_VERSION", "recordVersion", this::getRecordVersion, this::isRecordVersionUpdated, this::setRecordVersion));
    }

    /**
     * Map to column: AUTHOR_ID
     */
    public SqlColumn getAuthorId() {
        return authorId;
    }

    /**
     * Map to column: AUTHOR_ID
     */
    public boolean isAuthorIdUpdated() {
        return authorIdUpdated;
    }

    /**
     * Map to column: AUTHOR_ID
     */
    public void setAuthorId(BigInteger authorId) {
        this.authorId = authorId == null ? null : new DefaultValueColumn(authorId);
        this.authorIdUpdated = true;
    }

    /**
     * Map to column: AUTHOR_ID
     */
    public void setAuthorId(SqlColumn authorId) {
        this.authorId = authorId;
        this.authorIdUpdated = true;
    }

    /**
     * Gets 作者姓名
     * <p>Map to column: AUTHOR_NAME</p>
     */
    public SqlColumn getAuthorName() {
        return authorName;
    }

    /**
     * Gets 作者姓名
     * <p>Map to column: AUTHOR_NAME</p>
     */
    public boolean isAuthorNameUpdated() {
        return authorNameUpdated;
    }

    /**
     * Sets 作者姓名
     * <p>Map to column: AUTHOR_NAME</p>
     */
    public void setAuthorName(String authorName) {
        this.authorName = authorName == null ? null : new DefaultValueColumn(authorName);
        this.authorNameUpdated = true;
    }

    /**
     * Sets 作者姓名
     * <p>Map to column: AUTHOR_NAME</p>
     */
    public void setAuthorName(SqlColumn authorName) {
        this.authorName = authorName;
        this.authorNameUpdated = true;
    }

    /**
     * Map to column: NATIONALITY
     */
    public SqlColumn getNationality() {
        return nationality;
    }

    /**
     * Map to column: NATIONALITY
     */
    public boolean isNationalityUpdated() {
        return nationalityUpdated;
    }

    /**
     * Map to column: NATIONALITY
     */
    public void setNationality(String nationality) {
        this.nationality = nationality == null ? null : new DefaultValueColumn(nationality);
        this.nationalityUpdated = true;
    }

    /**
     * Map to column: NATIONALITY
     */
    public void setNationality(SqlColumn nationality) {
        this.nationality = nationality;
        this.nationalityUpdated = true;
    }

    /**
     * Map to column: CONTACT
     */
    public SqlColumn getContact() {
        return contact;
    }

    /**
     * Map to column: CONTACT
     */
    public boolean isContactUpdated() {
        return contactUpdated;
    }

    /**
     * Map to column: CONTACT
     */
    public void setContact(String contact) {
        this.contact = contact == null ? null : new DefaultValueColumn(contact);
        this.contactUpdated = true;
    }

    /**
     * Map to column: CONTACT
     */
    public void setContact(SqlColumn contact) {
        this.contact = contact;
        this.contactUpdated = true;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public SqlColumn getCreateDateTime() {
        return createDateTime;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public boolean isCreateDateTimeUpdated() {
        return createDateTimeUpdated;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public void setCreateDateTime(LocalDateTime createDateTime) {
        this.createDateTime = createDateTime == null ? null : new DefaultValueColumn(createDateTime);
        this.createDateTimeUpdated = true;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public void setCreateDateTime(SqlColumn createDateTime) {
        this.createDateTime = createDateTime;
        this.createDateTimeUpdated = true;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public SqlColumn getUpdateDateTime() {
        return updateDateTime;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public boolean isUpdateDateTimeUpdated() {
        return updateDateTimeUpdated;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public void setUpdateDateTime(LocalDateTime updateDateTime) {
        this.updateDateTime = updateDateTime == null ? null : new DefaultValueColumn(updateDateTime);
        this.updateDateTimeUpdated = true;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public void setUpdateDateTime(SqlColumn updateDateTime) {
        this.updateDateTime = updateDateTime;
        this.updateDateTimeUpdated = true;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public SqlColumn getDeleteDateTime() {
        return deleteDateTime;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public boolean isDeleteDateTimeUpdated() {
        return deleteDateTimeUpdated;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public void setDeleteDateTime(LocalDateTime deleteDateTime) {
        this.deleteDateTime = deleteDateTime == null ? null : new DefaultValueColumn(deleteDateTime);
        this.deleteDateTimeUpdated = true;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public void setDeleteDateTime(SqlColumn deleteDateTime) {
        this.deleteDateTime = deleteDateTime;
        this.deleteDateTimeUpdated = true;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public SqlColumn getCreateUserId() {
        return createUserId;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public boolean isCreateUserIdUpdated() {
        return createUserIdUpdated;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public void setCreateUserId(String createUserId) {
        this.createUserId = createUserId == null ? null : new DefaultValueColumn(createUserId);
        this.createUserIdUpdated = true;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public void setCreateUserId(SqlColumn createUserId) {
        this.createUserId = createUserId;
        this.createUserIdUpdated = true;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public SqlColumn getUpdateUserId() {
        return updateUserId;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public boolean isUpdateUserIdUpdated() {
        return updateUserIdUpdated;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public void setUpdateUserId(String updateUserId) {
        this.updateUserId = updateUserId == null ? null : new DefaultValueColumn(updateUserId);
        this.updateUserIdUpdated = true;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public void setUpdateUserId(SqlColumn updateUserId) {
        this.updateUserId = updateUserId;
        this.updateUserIdUpdated = true;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public SqlColumn getDeleteUserId() {
        return deleteUserId;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public boolean isDeleteUserIdUpdated() {
        return deleteUserIdUpdated;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public void setDeleteUserId(String deleteUserId) {
        this.deleteUserId = deleteUserId == null ? null : new DefaultValueColumn(deleteUserId);
        this.deleteUserIdUpdated = true;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public void setDeleteUserId(SqlColumn deleteUserId) {
        this.deleteUserId = deleteUserId;
        this.deleteUserIdUpdated = true;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public SqlColumn getRecordVersion() {
        return recordVersion;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public boolean isRecordVersionUpdated() {
        return recordVersionUpdated;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public void setRecordVersion(Long recordVersion) {
        this.recordVersion = recordVersion == null ? null : new DefaultValueColumn(recordVersion);
        this.recordVersionUpdated = true;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public void setRecordVersion(SqlColumn recordVersion) {
        this.recordVersion = recordVersion;
        this.recordVersionUpdated = true;
    }

    @Override
    public Optional<ColumnDescriptor<?>> findColumnDescriptor(Class<? extends ColumnFunction> columnFunctionClass) {
        return Optional.ofNullable(functionMap.get(argNotNull(columnFunctionClass, "columnFunctionClass")));
    }
}
